package com.cnzhy.spring.framework;

import com.cnzhy.spring.annotation.MyRequestParamMapping;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class Handler {
    protected Object controller;
    protected Method method;
    protected Pattern pattern;
    protected Map<String, Integer> paramIndexMapping;

    protected Handler(Pattern pattern, Object controller, Method method) {
        super();
        this.controller = controller;
        this.method = method;
        this.pattern = pattern;
        this.paramIndexMapping = new HashMap<>();
        putParamIndexMapping(method);
    }

    public Object getController() {
        return controller;
    }

    public void setController(Object controller) {
        this.controller = controller;
    }

    public Method getMethod() {
        return method;
    }

    public void setMethod(Method method) {
        this.method = method;
    }

    public Pattern getPattern() {
        return pattern;
    }

    public void setPattern(Pattern pattern) {
        this.pattern = pattern;
    }

    public Map<String, Integer> putParamIndexMapping(Method method) {
        // 提取方法中加了注解的参数
        Annotation[][] pa = method.getParameterAnnotations();
        for (int i = 0; i < pa.length; i++) {
            for (Annotation a : pa[i]) {
                if (a instanceof MyRequestParamMapping) {
                    String paranName = ((MyRequestParamMapping) a).value();
                    if (!"".equals(paranName.trim())) {
                        paramIndexMapping.put(paranName, i);
                    }
                }
            }
        }
        // 提取方法中的request和response参数
        Class<?>[] paramTypes = method.getParameterTypes();
        for (int i = 0; i < paramTypes.length; i++) {
            if (paramTypes[i] == HttpServletRequest.class || paramTypes[i] == HttpServletResponse.class) {
                paramIndexMapping.put(paramTypes[i].getName(), i);
            }
        }
        return paramIndexMapping;
    }

    public Handler getHandler(HttpServletRequest req) throws Exception {
        if (MyDispatcherServlet.getHandlerMappingList().isEmpty()) {
            return null;
        }
        String url = req.getRequestURI();
        String contextPath = req.getContextPath();
        url = url.replace(contextPath, "").replaceAll("/+", "/");
        for (Handler handler : MyDispatcherServlet.getHandlerMappingList()) {
            try {
                Matcher matcher = handler.pattern.matcher(url);
                if (matcher.matches()) {
                    return handler;
                }
            } catch (Exception e) {

            }
        }
        return null;
    }

    public void setParamIndexMapping(Map<String, Integer> paramIndexMapping) {
        this.paramIndexMapping = paramIndexMapping;
    }
}
